﻿using MESMian.Common;
using Microsoft.Data.SqlClient;
using NPOI.SS.UserModel;
using NPOI.XSSF.UserModel;
using System.Configuration;
using System.Data;

namespace MESMian.Test
{
    public partial class ListBase : Form
    {
        public ListBase()
        {
            InitializeComponent();
            Load += ParentTeacher_Load;
            dtpCreateTimeStart.ValueChanged += DtpCreateTimeStart_ValueChanged;
            dtpCreateTimeEnd.ValueChanged += DtpCreateTimeEnd_ValueChanged;
            btnClearCreateTimeStart.Click += BtnClearCreateTimeStart_Click;
            btnClearCreateTimeEnd.Click += BtnClearCreateTimeEnd_Click;
            dataGridView1.CellPainting += DataGridView1_CellPainting;
            dataGridView1.CellMouseClick += DataGridView1_CellMouseClick;
            dataGridView1.CellFormatting += DataGridView1_CellFormatting;
            ucPager1.PagerEvent += UcPager1_PagerEvent;
            btnSearch.Click += BtnSearch_Click;
            btnAdd.Click += BtnAdd_Click;
            btnImport.Click += BtnImport_Click;
            btnExport.Click += BtnExport_Click;

        }

        private void BtnExport_Click(object? sender, EventArgs e)
        {
            SaveFileDialog saveFileDialog = new SaveFileDialog();
            saveFileDialog.Filter = "Excel files (*.xlsx)|*.xlsx";
            saveFileDialog.Title = "选择导出文件保存位置";
            saveFileDialog.FileName = GetFileName();

            if (saveFileDialog.ShowDialog() == DialogResult.OK)
            {
                Export(dataGridView1, saveFileDialog.FileName);
            }
        }

        private void Export(DataGridView dgv, string fileName)
        {
            try
            {
                IWorkbook wb = new XSSFWorkbook();
                //NPOI 使用HSSFWorkbook 类来处理 xls，XSSFWorkbook 类来处理 xlsx。
                //它们都继承接口 IWorkbook，通过 IWorkbook 来统一处理 xls 和 xlsx 格式的文件
                ISheet sheet = wb.CreateSheet();
                IRow row;
                //获取DataGridView的列名，其中 i 表示低级列，i从0开始
                row = sheet.CreateRow(0);
                // 生成标题，注意第一列是“操作”列，不处理
                for (int k = 1; k < dgv.Columns.Count; k++)
                {
                    row.CreateCell(k - 1).SetCellValue(dgv.Columns[k].HeaderText.ToString());
                }
                for (int i = 0; i < dgv.Rows.Count; i++)
                {
                    row = sheet.CreateRow(i + 1);
                    for (int k = 1; k < dgv.Columns.Count; k++)
                    {
                        string? value = dgv.Rows[i].Cells[k].Value == null ? "" : dgv.Rows[i].Cells[k].Value.ToString();
                        row.CreateCell(k - 1).SetCellValue(value);
                    }
                }
                using (var fs = new FileStream(fileName, FileMode.OpenOrCreate, FileAccess.ReadWrite))
                {
                    wb.Write(fs); //写入到Excel中
                }
                MessageBox.Show("保存成功，文件名：" + fileName, "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        /// <summary>
        /// 获取导出的默认文件名，必须重写
        /// </summary>
        /// <returns></returns>
        public virtual string GetFileName()
        {
            return $"产品类型表_{DateTime.Now:yyyyMMddHHmmss}.xlsx";
        }

        private void BtnImport_Click(object? sender, EventArgs e)
        {
            OpenFileDialog ofd = new OpenFileDialog();
            ofd.Filter = "Excel files (*.xlsx)|*.xlsx";
            if (ofd.ShowDialog() == DialogResult.OK)
            {
                string connectionString = ConfigurationManager.ConnectionStrings["ConnDatabase"].ConnectionString;
                Import(ofd.FileName, connectionString, GetTableName());

            }
        }


        /// <summary>
        /// 获取导入的表名，必须重写
        /// </summary>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public virtual string GetTableName()
        {
            return "ProductCategories";
        }

        private void Import(string excelFilePath, string connectionString, string tableName)
        {
            try
            {
                using (FileStream fileStream = new FileStream(excelFilePath, FileMode.Open, FileAccess.Read))
                {
                    IWorkbook workbook = new XSSFWorkbook(fileStream);
                    ISheet sheet = workbook.GetSheetAt(0);
                    DataTable dt = new DataTable();
                    bool firstRow = true;
                    for (int i = 0; i < sheet.LastRowNum + 1; i++)
                    {
                        IRow row = sheet.GetRow(i);
                        if (row == null) continue;
                        if (firstRow)
                        {
                            for (int j = 0; j < row.Cells.Count; j++)
                            {
                                if (row.GetCell(j) != null) dt.Columns.Add(row.GetCell(j).ToString());
                            }
                            firstRow = false;
                        }
                        else
                        {
                            DataRow dataRow = dt.NewRow();
                            for (int j = 0; j < row.Cells.Count; j++)
                            {
                                if (row.GetCell(j) != null) dataRow[j] = row.GetCell(j).ToString();
                            }
                            dt.Rows.Add(dataRow);
                        }
                    }
                    workbook.Close();
                    using (SqlBulkCopy bulkCopy = new SqlBulkCopy(connectionString))
                    {
                        bulkCopy.DestinationTableName = tableName;
                        bulkCopy.WriteToServer(dt);
                    }
                    ucPager1.CurrentPage = 1;
                    ucPager1.GetPagerData();
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void BtnAdd_Click(object? sender, EventArgs e)
        {
            ShowAddForm();
        }

        /// <summary>
        /// 打开添加窗体，必须重写
        /// </summary>
        public virtual void ShowAddForm()
        {

        }

        private void BtnSearch_Click(object? sender, EventArgs e)
        {
            ucPager1.CurrentPage = 1;
            ucPager1.GetPagerData();
        }

        private void UcPager1_PagerEvent(int currentPage, int pageSize, out int totalCount)
        {
            totalCount = BindDataGridView();
            dataGridView1.EnableHeadersVisualStyles = false;  // 禁用默认的视觉样式
            dataGridView1.ColumnHeadersDefaultCellStyle.BackColor = Color.LightBlue;

            /* dataGridView1.MultiSelect = false;*/  // 禁用多行选择（如果只想选中一行）
            dataGridView1.SelectionMode = DataGridViewSelectionMode.FullRowSelect; // 设置 DataGridView 的选择模式为整行选择
            dataGridView1.DefaultCellStyle.SelectionBackColor = Color.LightGreen; // 选中行的背景色
            dataGridView1.DefaultCellStyle.SelectionForeColor = Color.Black;
            // 取消已选中的单元格的单元格级别选中状态
            dataGridView1.CurrentCell = null;

            dataGridView1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;
            dataGridView1.Columns["Status"].Visible = false;
            dataGridView1.Columns["CreateUserId"].Visible = false;
            dataGridView1.Columns["LastUpdateUserId"].Visible = false;

            dataGridView1.Columns["Status"].HeaderText = "状态值";
            dataGridView1.Columns["StatusText"].HeaderText = "状态";
            dataGridView1.Columns["CreateUserId"].HeaderText = "创建人Id";
            dataGridView1.Columns["CreateUserName"].HeaderText = "创建人";
            dataGridView1.Columns["CreateTime"].HeaderText = "创建日期";
            dataGridView1.Columns["LastUpdateUserId"].HeaderText = "修改人Id";
            dataGridView1.Columns["LastUpdateUserName"].HeaderText = "修改人";
            dataGridView1.Columns["LastUpdateTime"].HeaderText = "修改日期";

            dataGridView1.Columns["CreateTime"].DefaultCellStyle.Format = "yyyy-MM-dd HH:mm";
            dataGridView1.Columns["LastUpdateTime"].DefaultCellStyle.Format = "yyyy-MM-dd HH:mm";

            dataGridView1.Columns["CreateTime"].Width = 200;
            dataGridView1.Columns["LastUpdateTime"].Width = 200;

            if (!dataGridView1.Columns.Contains("Operate"))
            {
                dataGridView1.Columns.Add("Operate", "操作");
                dataGridView1.Columns["Operate"].Width = 300;
            }
        }
        /// <summary>
        /// 绑定网格，必须重写
        /// </summary>
        /// <returns></returns>
        public virtual int BindDataGridView()
        {
            return 0;
        }

        private void DataGridView1_CellFormatting(object? sender, DataGridViewCellFormattingEventArgs e)
        {
            if (dataGridView1.Columns[e.ColumnIndex].Name == "StatusText" && e.Value != null)
            {
                string? value = e.Value.ToString();
                if (value != null && value.Equals("禁用"))
                {
                    if (e.CellStyle != null) e.CellStyle.ForeColor = Color.Red;
                }
            }
        }

        private void DataGridView1_CellMouseClick(object? sender, DataGridViewCellMouseEventArgs e)
        {
            if (e.ColumnIndex >= 0 && e.RowIndex >= 0)
            {
                Point curPosition = e.Location;
                if (dataGridView1.Columns[e.ColumnIndex].Name == "Operate")
                {
                    RectangleF rectDisable, rectEnable, rectModify, rectDetail, rectReserve1, rectReserve2;
                    PaintOperateCellMouseClick(e, out rectDisable, out rectEnable, out rectModify, out rectDetail, out rectReserve1, out rectReserve2);
                    Operate(e, curPosition, rectDisable, rectEnable, rectModify, rectDetail, rectReserve1, rectReserve2);
                }
            }
        }

        /// <summary>
        /// 禁用，启用，编辑，详情的业务逻辑，必须重写
        /// </summary>
        /// <param name="e"></param>
        /// <param name="curPosition"></param>
        /// <param name="rectDisable"></param>
        /// <param name="rectEnable"></param>
        /// <param name="rectModify"></param>
        /// <param name="rectDetail"></param>
        /// <param name="rectReserve1"></param>
        /// <param name="rectReserve2"></param>
        /// <exception cref="NotImplementedException"></exception>
        public virtual void Operate(DataGridViewCellMouseEventArgs e, Point curPosition, RectangleF rectDisable, RectangleF rectEnable, RectangleF rectModify, RectangleF rectDetail, RectangleF rectReserve1, RectangleF rectReserve2)
        {

        }

        public virtual void PaintOperateCellMouseClick(DataGridViewCellMouseEventArgs e, out RectangleF rectDisable, out RectangleF rectEnable, out RectangleF rectModify, out RectangleF rectDetail, out RectangleF rectReserve1, out RectangleF rectReserve2)
        {
            Graphics g = dataGridView1.CreateGraphics();
            Font myFont = new Font("宋体", 9F, FontStyle.Regular, GraphicsUnit.Point, 134);
            SizeF sizeDisable = g.MeasureString("禁用", myFont);
            SizeF sizeEnable = g.MeasureString("启用", myFont);
            SizeF sizeModify = g.MeasureString("编辑", myFont);
            SizeF sizeDetail = g.MeasureString("详情", myFont);
            float fDisable = sizeDisable.Width / (sizeDisable.Width + sizeEnable.Width + sizeModify.Width + sizeDetail.Width);
            float fEnable = sizeEnable.Width / (sizeDisable.Width + sizeEnable.Width + sizeModify.Width + sizeDetail.Width);
            float fModify = sizeModify.Width / (sizeDisable.Width + sizeEnable.Width + sizeModify.Width + sizeDetail.Width);
            float fDetail = sizeDetail.Width / (sizeDisable.Width + sizeEnable.Width + sizeModify.Width + sizeDetail.Width);

            Rectangle rectTotal = new Rectangle(0, 0, dataGridView1.Columns[e.ColumnIndex].Width, dataGridView1.Rows[e.RowIndex].Height);
            rectDisable = new RectangleF(rectTotal.Left, rectTotal.Top, rectTotal.Width * fDisable, rectTotal.Height);
            rectEnable = new RectangleF(rectDisable.Right, rectTotal.Top, rectTotal.Width * fEnable, rectTotal.Height);
            rectModify = new RectangleF(rectEnable.Right, rectTotal.Top, rectTotal.Width * fModify, rectTotal.Height);
            rectDetail = new RectangleF(rectModify.Right, rectTotal.Top, rectTotal.Width * fDetail, rectTotal.Height);
            rectReserve1 = new RectangleF();
            rectReserve2 = new RectangleF();
        }

        private void DataGridView1_CellPainting(object? sender, DataGridViewCellPaintingEventArgs e)
        {
            if (e.ColumnIndex >= 0 && e.RowIndex >= 0)
            {
                if (dataGridView1.Columns[e.ColumnIndex].Name == "Operate")
                {
                    PaintOperate(e);
                }

            }
        }

        public virtual void PaintOperate(DataGridViewCellPaintingEventArgs e)
        {
            StringFormat sf = (StringFormat)StringFormat.GenericDefault.Clone();
            sf.Alignment = StringAlignment.Center;
            sf.LineAlignment = StringAlignment.Center;
            sf.Trimming = StringTrimming.EllipsisCharacter;

            e.PaintBackground(e.CellBounds, false);

            Font myFont = new Font("微软雅黑", 9F, FontStyle.Regular, GraphicsUnit.Point, 134);
            if (e.Graphics != null)
            {
                SizeF sizeDisable = e.Graphics.MeasureString("禁用", myFont);
                SizeF sizeEnable = e.Graphics.MeasureString("启用", myFont);
                SizeF sizeModify = e.Graphics.MeasureString("编辑", myFont);
                SizeF sizeDetail = e.Graphics.MeasureString("详情", myFont);
                float fDisable = sizeDisable.Width / (sizeDisable.Width + sizeEnable.Width + sizeModify.Width + sizeDetail.Width);
                float fEnable = sizeEnable.Width / (sizeDisable.Width + sizeEnable.Width + sizeModify.Width + sizeDetail.Width);
                float fModify = sizeModify.Width / (sizeDisable.Width + sizeEnable.Width + sizeModify.Width + sizeDetail.Width);
                float fDetail = sizeDetail.Width / (sizeDisable.Width + sizeEnable.Width + sizeModify.Width + sizeDetail.Width);

                RectangleF rectDisable = new RectangleF(e.CellBounds.Left, e.CellBounds.Top, e.CellBounds.Width * fDisable, e.CellBounds.Height);
                RectangleF rectEnable = new RectangleF(rectDisable.Right, e.CellBounds.Top, e.CellBounds.Width * fEnable, e.CellBounds.Height);
                RectangleF rectModify = new RectangleF(rectEnable.Right, e.CellBounds.Top, e.CellBounds.Width * fModify, e.CellBounds.Height);
                RectangleF rectDetail = new RectangleF(rectModify.Right, e.CellBounds.Top, e.CellBounds.Width * fDetail, e.CellBounds.Height);

                e.Graphics.DrawString("禁用", myFont, Brushes.Red, rectDisable, sf);
                e.Graphics.DrawString("启用", myFont, new SolidBrush(Color.FromArgb(1, 62, 153)), rectEnable, sf);
                e.Graphics.DrawString("编辑", myFont, new SolidBrush(Color.FromArgb(1, 62, 153)), rectModify, sf);
                e.Graphics.DrawString("详情", myFont, new SolidBrush(Color.FromArgb(1, 62, 153)), rectDetail, sf);
                e.Handled = true;
            }
        }

        private void BtnClearCreateTimeEnd_Click(object? sender, EventArgs e)
        {
            dtpCreateTimeEnd.Format = DateTimePickerFormat.Custom;
            dtpCreateTimeEnd.CustomFormat = " ";
        }

        private void BtnClearCreateTimeStart_Click(object? sender, EventArgs e)
        {
            dtpCreateTimeStart.Format = DateTimePickerFormat.Custom;
            dtpCreateTimeStart.CustomFormat = " ";
        }

        private void DtpCreateTimeEnd_ValueChanged(object? sender, EventArgs e)
        {

            dtpCreateTimeEnd.Format = DateTimePickerFormat.Custom;
            dtpCreateTimeEnd.CustomFormat = "yyyy-MM-dd";
        }

        private void DtpCreateTimeStart_ValueChanged(object? sender, EventArgs e)
        {
            dtpCreateTimeStart.Format = DateTimePickerFormat.Custom;
            dtpCreateTimeStart.CustomFormat = "yyyy-MM-dd";
        }

        private void ParentTeacher_Load(object? sender, EventArgs e)
        {
            BindStatus();
            SettingDateFormat();
        }

        private void SettingDateFormat()
        {
            dtpCreateTimeStart.Format = DateTimePickerFormat.Custom;
            dtpCreateTimeStart.CustomFormat = " ";

            dtpCreateTimeEnd.Format = DateTimePickerFormat.Custom;
            dtpCreateTimeEnd.CustomFormat = " ";
        }

        private void BindStatus()
        {
            cbbStatus.Items.Clear();
            List<Status> list = new List<Status>()
            {
                new Status(){Code=-1,Text ="全部"},
                new Status(){Code=0,Text="正常"},
                new Status(){Code=1,Text="禁用"}
            };

            cbbStatus.DataSource = list;
            cbbStatus.DisplayMember = "Text";
            cbbStatus.ValueMember = "Code";
        }
    }
}
